/********************************************
 * 功能说明: 
 * 模块名称: 
 * 系统名称: 
 * 软件版权: 北京银杉金服科技有限公司
 * 系统版本: 1.0.0
 * 开发人员: zhangfb
 * 开发时间: 2019/1/13 18:36
 * 审核人员: 
 * 相关文档: 
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.hyacinth.server.bootstrap;

import com.hyacinth.server.bean.AuroraBeanManager;
import com.hyacinth.server.config.AppConfig;
import com.hyacinth.server.context.AuroraContext;
import com.hyacinth.server.enums.ServerChannel;
import com.hyacinth.server.thread.ThreadLocalHolder;
import com.hyacinth.server.util.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.hyacinth.server.constant.Constant.SystemProperties.APPLICATION_THREAD_SHUTDOWN_NAME;

/**
 * @author zhangfb
 * @version 1.0.0.1
 * @since JDK 1.8
 */
public abstract class AuroraBootstrap implements Bootstrap{

    private static final Logger LOGGER = LoggerFactory.getLogger(AuroraBootstrap.class);

    private static final AppConfig appConfig = AppConfig.getInstance() ;

    /**
     * 加载服务通道
     * @return 启动引导
     */
    public static AuroraBootstrap loadServerChannel() {
        ServerChannel serverChannel = appConfig.getServerChannel();
        Assert.notNull(appConfig.getServerChannel(), "server channel is null！");
        AuroraBootstrap bootstrap = null;
        switch (serverChannel) {
            case Netty:
                bootstrap = new NettyBootStrap();
                break;
            case HttpClient:
                break;
            case WebSocket:
                break;
        }
        return bootstrap;
    }


    @Override
    public void startAurora() throws Exception {
        // 服务启动
        startServer(appConfig.getPort());

        // 打印启动日志
        printStartLog();

        // 注册关闭服务钩子
        registShutdownHook();

        // 注册服务
        joinServer();
    }

    /**
     * 打印启动日志
     */
    private void printStartLog() {
        Long start = ThreadLocalHolder.getLocalTime();
        long end = System.currentTimeMillis();
        LOGGER.info("Aurora started on port: {}.cost {}ms", appConfig.getPort(), end - start);
        LOGGER.info(">> access http://{}:{}{} <<","127.0.0.1",appConfig.getPort(),appConfig.getServerContextPath());
    }


    /**
     * 注册关闭钩子
     */
    private void registShutdownHook() {
        ShutDownThread shutDownThread = new ShutDownThread();
        shutDownThread.setName(APPLICATION_THREAD_SHUTDOWN_NAME);
        Runtime.getRuntime().addShutdownHook(shutDownThread);
    }

    /**
     * 关闭线程
     */
    private class ShutDownThread extends Thread {
        @Override
        public void run() {
            LOGGER.info("Aurora server stop...");

            // 删除上下文
            AuroraContext.removeContext();
            // 释放bean
            AuroraBeanManager.getInstance().releaseBean();
            // 关闭资源
            releaseResource();

            LOGGER.info("Aurora server has been successfully stopped.");
        }

    }

    protected abstract void startServer(int port) throws Exception;

    protected abstract void joinServer();

    protected abstract void releaseResource();


}
